package net.zrnecko.bowlingnumbers.entity;

import java.util.StringTokenizer;
import javax.persistence.Entity;
import javax.persistence.Table;
import org.hibernate.validator.Pattern;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.log.Log;

/**
 *
 * @author zrnecko
 */

@Entity
@Name("frameGame")
@Scope(ScopeType.CONVERSATION)
@Table(name = "game")
public class FrameGame extends ResultGame {

	private static final long serialVersionUID = 1L;
	@Logger
	private static Log log;

	@Pattern(regex = "(|(([1-9-][1-9-/]|X)\\|){9}" + "(XX(X|[1-9-])|X[1-9-][1-9-/]|[1-9-][1-9-]|[1-9-]/[1-9X]))")
	private String frameDetails;

	@Override
	public void setResult(int result) {
		throw new UnsupportedOperationException("Result has to be set through setFrameDetails!");
	};

	public String getFrameDetails() {

		return frameDetails;
	}

	public void setFrameDetails(String frameDetails) {
		this.frameDetails = frameDetails;
		log.debug("Frame details set to " + frameDetails);
		if (!frameDetails.equals("")) {
			computeFrameResult();
		}
	}

	private void computeFrameResult() {
		StringTokenizer tokenizer = new StringTokenizer(frameDetails, "|");
		int tmpResult = 0;
		boolean buildingOnSpare = false;
		boolean buildingOnStrike = false;
		boolean buildingOn2Strikes = false;
		boolean isStrike = false;
		boolean isSpare = false;
		String frameString;
		Integer strikeShotPinFall;
		Integer spareShotPinFall;
		Integer thirdShotPinFall = 0;
		for (int i = 0; i < 9; i++) {
			frameString = tokenizer.nextToken();
			if (frameString.length() == 1) {
				isStrike = true;
				isSpare = false;
				strikeShotPinFall = 10;
				spareShotPinFall = 0;
			} else if (frameString.endsWith("/")) {
				isStrike = false;
				isSpare = true;
				strikeShotPinFall = frameString.substring(0,1).equals("-") ? 0 : Integer.parseInt(frameString.substring(0,1));
				log.debug("Strikeshot pinfall is: " + strikeShotPinFall);
				spareShotPinFall = 10 - strikeShotPinFall;
				log.debug("Spareshot pinfall is: " + spareShotPinFall);
			} else {
				isStrike = false;
				isSpare = false;
				strikeShotPinFall = frameString.substring(0, 1).equals("-") ? 0 : Integer.parseInt(frameString.substring(0,1));
				log.debug("Strikeshot pinfall is: " + strikeShotPinFall);
				spareShotPinFall = frameString.substring(1, 2).equals("-") ? 0 : Integer.parseInt(frameString.substring(1,2));
				log.debug("Spareshot pinfall is: " + spareShotPinFall);
			}
			if (!buildingOnSpare && !buildingOnStrike && !buildingOn2Strikes) {
				tmpResult += strikeShotPinFall + spareShotPinFall;
				log.debug("Building on nothing");
			}
			if (buildingOnSpare) {
				tmpResult += 2 * strikeShotPinFall + spareShotPinFall;
				log.debug("Building on spare");
			}
			if (buildingOnStrike) {
				tmpResult += 2 * strikeShotPinFall + 2 * spareShotPinFall;
				log.debug("Building on strike");
			}
			if (buildingOn2Strikes) {
				tmpResult += 3 * strikeShotPinFall + 2 * spareShotPinFall;
				log.debug("Building on 2 strikes");
			}
			log.debug("Result after frame " + (i + 1) + ": " + tmpResult);

			if (isStrike) {
				if (buildingOnStrike || buildingOn2Strikes) {
					buildingOn2Strikes = true;
					buildingOnStrike = false;
				} else {
					buildingOnStrike = true;
				}
				buildingOnSpare = false;
			} else if (isSpare) {
				buildingOnSpare = true;
				buildingOnStrike = false;
				buildingOn2Strikes = false;
			} else {
				buildingOnSpare = false;
				buildingOnStrike = false;
				buildingOn2Strikes = false;
			}

		}
		frameString = tokenizer.nextToken();
		String frameCharOne = frameString.substring(0,1);
		String frameCharTwo = frameString.substring(1,2);
		if (frameString.length() == 3) {
			String frameCharThree = frameString.substring(2,3);
			if (frameCharOne.equals("X")) {
				strikeShotPinFall = 10;
				if (frameCharTwo.equals("X")) {
					spareShotPinFall = 10;
					if (frameCharThree.equals("X")) {
						thirdShotPinFall = 10;
					} else {
						thirdShotPinFall = frameCharThree.equals("-") ? 0 : Integer.parseInt(frameCharThree);
					}
				} else {
					spareShotPinFall = frameCharTwo.equals("-") ? 0 : Integer.parseInt(frameCharTwo);
					if (frameCharThree.equals("/")) {
						thirdShotPinFall = 10 - spareShotPinFall;
					} else {
						thirdShotPinFall = frameCharThree.equals("-") ? 0 : Integer.parseInt(frameCharThree);
					}
				}
			} else {
				strikeShotPinFall = frameCharOne.equals("-") ? 0 : Integer.parseInt(frameString.substring(0, 1));
				spareShotPinFall = 10 - strikeShotPinFall;
			}
		} else { 
			strikeShotPinFall = frameCharOne.equals("-") ? 0 : Integer.parseInt(frameCharOne);
			spareShotPinFall = frameCharTwo.equals("-") ? 0 : Integer.parseInt(frameCharTwo);
			thirdShotPinFall = 0;
		}
		if (!buildingOnSpare && !buildingOnStrike && !buildingOn2Strikes) {
			tmpResult += strikeShotPinFall + spareShotPinFall;
		}
		if (buildingOnSpare) {
			tmpResult += 2 * strikeShotPinFall + spareShotPinFall;
		}
		if (buildingOnStrike) {
			tmpResult += 2 * strikeShotPinFall + 2 * spareShotPinFall;
		}
		if (buildingOn2Strikes) {
			tmpResult += 3 * strikeShotPinFall + 2 * spareShotPinFall;
		}
		tmpResult += thirdShotPinFall;
		log.debug("Result after frame 10: " + tmpResult);
		log.debug("Setting result to " + tmpResult);
		super.setResult(tmpResult);
	}
}
